﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using Telerik.OpenAccess;
using Bids.Core.DomainObjects;
using Bids.Core.Infrastructure;

namespace Bids.Data
{
    public interface IRepository<TEntity> where TEntity : IEntity
    {
        void Add(TEntity instance);
       
        void Add(IEnumerable<TEntity> instances);
       
        void Remove(TEntity instance);
       
        void Remove(IEnumerable<TEntity> instances);
       
        void Update(TEntity instance);
        
        void Update(IEnumerable<TEntity> instances);
        
        TEntity Find(object id);
        TEntity Find(Expression<Func<TEntity, bool>> predicate);
        IQueryable<TEntity> FindAll();
        IQueryable<TEntity> Where(Expression<Func<TEntity, bool>> predicate);
        IQueryable<TEntity> Where(string where);
        IQueryable<TEntity> Where(string where,string order);
        int Count();
        int Count(Expression<Func<TEntity, bool>> predicate);
        bool Exists(Expression<Func<TEntity, bool>> predicate);
    }
    /// <summary>
    /// 仓储
    /// </summary>
    /// <typeparam name="TEntity"></typeparam>
    public class Repository<TEntity> : IRepository<TEntity> where TEntity :  IEntity
    {
        protected IDataContext Context { get; private set; }

        public Repository(IDataContext iDataContext)
        {
            Context = iDataContext;
        }


        public virtual void Add(TEntity instance)
        {
            Context.Add(instance);
            Context.SaveChanges();
        }
       

        public virtual void Add(IEnumerable<TEntity> instances)
        {
            Context.Add(instances);
            Context.SaveChanges();
        }

        

        public virtual void Remove(TEntity instance)
        {
            Context.Delete(instance);
            Context.SaveChanges();
        }

       

        public virtual void Remove(IEnumerable<TEntity> instances)
        {
            Context.Delete(instances);
            Context.SaveChanges();
        }
        
        public virtual void Update(TEntity instance)
        {
            Context.SaveChanges();
        }
       
        public virtual void Update(IEnumerable<TEntity> instances)
        {
            Context.SaveChanges();
        }
        
        public virtual TEntity Find(object id)
        {
            ObjectKey key = new ObjectKey(typeof(TEntity).Name, id);
            return Context.GetObjectByKey<TEntity>(key);
        }

        public virtual TEntity Find(Expression<Func<TEntity, bool>> predicate)
        {
            return this.Context.GetAll<TEntity>().SingleOrDefault(predicate);
        }

        public virtual IQueryable<TEntity> FindAll()
        {
            
                return Context.GetAll<TEntity>();
            
        }

        public virtual IQueryable<TEntity> Where(Expression<Func<TEntity, bool>> predicate)
        {
            return Context.GetAll<TEntity>().Where(predicate);
        }
        public IQueryable<TEntity> Where(string where)
        {
            return Context.GetAll<TEntity>().Where(where);
        }
        public IQueryable<TEntity> Where(string where, string order)
        {
            return Context.GetAll<TEntity>().Where(where,order);
        }
        public virtual int Count()
        {
            return Context.GetAll<TEntity>().Count();
        }

        public virtual int Count(Expression<Func<TEntity, bool>> predicate)
        {
            return Context.GetAll<TEntity>().Count(predicate);
        }

        public virtual bool Exists(Expression<Func<TEntity, bool>> predicate)
        {
            return Context.GetAll<TEntity>().Any(predicate);
        }
    }
}